from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views import View
from rest_framework.response import Response
from rest_framework.views import APIView

from z_Userapp.MyPlant import SimpleFactory
from z_Userapp.MyRedisQueue import RedisQueue
from z_Userapp.MyThread import dojob, MessageModel
from z_Userapp.models import UserModel, WorkOrderModel, StorageModel, NestedList, FaModel
import redis
from z_Userapp.sers import UserSer, UserSer1, WorkOrderSer, MessageSer, FaSer
from z_Userapp.test_celery_updateuser import detail_updateuser
import asyncio


# 注册
class Register(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        try:
            user = UserModel(username=username, password=password)
            user.save()
            return Response({'code': 200, 'msg': '恭喜您，注册成功'})
        except Exception as e:
            print(str(e))
            return Response({'code': 405, 'msg': 'Sorry，用户已存在'})


# 登录
class Login(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        r = redis.Redis()
        if r.get(username + "black"):
            return Response({'msg': 'Sorry，您的账户已经被锁定了，30分钟之后重试', 'code': 400})
        user = UserModel.objects.filter(username=username, password=password).first()
        if user:
            return Response({'msg': '登录成功', 'code': 200, 'id': user.id, 'user_level': user.user_level})

        # 判断是否存在该键值对,如果不存在,则进行创建
        if r.get(username) == None:
            r.set(username, 0)

        #  如果是第一次密码错误,开始计时
        if int(r.get(username)) == 0:
            r.expire(username, 200)
            # 累加
            r.incrby(username, 1)
            return Response({"msg": "您输入的用户名或密码错误", 'code': 400})

        else:
            # 在五分钟错误五次 进行封禁
            if int(r.get(username)) == 5:
                r.set(username + "black", str(password))
                # 封禁时间
                r.expire(username + "black", 1800)
                return Response({"msg": "您的账号被锁定30分钟", 'code': 400})
            # 进行累加
            r.incrby(username, 1)
            return Response({"msg": "用户名或密码错误", 'code': 400, })


# 用户管理页面-增删改查
class UserView(APIView):
    # 注册 --  增 post
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        try:
            user = UserModel(username=username, password=password)
            user.save()
            return Response({'code': 200, 'msg': '用户增加成功'})
        except Exception as e:
            print(str(e))
            return Response({'code': 405, 'msg': 'Sorry，用户已存在'})

    # 删除用户 - delete
    def delete(self, request):
        id = request.GET.get('id')
        UserModel.objects.filter(id=id).delete()
        return Response({'msg': '成功删除用户', 'code': 200})

    # 修改用户信息 - put
    def put(self, request):
        id = request.query_params.get('id')
        print(id)
        username = request.data.get('username')
        print(username)
        password = request.data.get('password')
        print(password)
        UserModel.objects.filter(id=id).update(username=username, password=password)
        return Response({'msg': '成功修改用户信息', 'code': 200})

    # 查找用户信息 - get
    def get(self, request):
        queryset = UserModel.objects.all()
        ser = UserSer(queryset, many=True)
        return Response({'data': ser.data, 'msg': '查询所有用户成功', 'code': 200})


# 用户管理页面-根据用户名查找用户
class ShowUserView(APIView):
    def get(self, request):
        # 根据名字查找
        username = request.GET.get('username')
        queryset = UserModel.objects.filter(username=username)
        ser = UserSer1(queryset, many=True)
        return Response(ser.data)


# 用户详情
class DetailUserView(APIView):
    # 查看所有用户
    def get(self, request):
        queryset = UserModel.objects.all()
        ser = UserSer1(queryset, many=True)
        return Response({'data': ser.data, 'msg': '查询所有用户成功', 'code': 200})

    # 更改用户名和密码
    # def put(self, request):
    #     username = request.GET.get('username')
    #     new_user = request.data.get('new_user', username)
    #     print(username, new_user)
    #     return Response(detail_updateuser(username, new_user))


r = RedisQueue('queue')


# 修改用户名
class UpdateUserView(APIView):
    def put(self, request):
        # 获取id
        id = request.GET.get('id', None)
        # 用户名
        new_user = request.data.get('new_user', None)
        # 用户等级
        user_level = request.data.get('user_level', None)
        # 入队
        r.put(f'{id, new_user, user_level}')
        # r.order()
        return Response({'msg': '正在审核中，请耐心等待'})


# 修改用户名后获取结果
class GetJob(APIView):
    def get(self, request):
        # 出队
        id = request.query_params.get('id')
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        res = loop.run_until_complete(dojob())
        loop.close()
        a = r.hget('lz', id)
        print(a)
        if a.decode() == '200':
            return Response({"msg": '修改成功'})
        else:
            return Response({'msg': '用户名重复'})
            # 判断修改的用户名和数据库的用户名是否重复


authority = 1


# 返回中间件
class MiddleView(APIView):
    # 获取
    def get(self, request):
        return Response({'middle': authority == request.level})

    def put(self, request):
        global authority
        authority = int(not authority)
        return Response({'msg': '修改成功'})


# 三方登录导包
import time
import hmac
import base64
from hashlib import sha256
import urllib
import json
import requests


# 钉钉三方登录
def ding_back(request):
    appid = 'dingoar91fvryq6pugb1nx'
    redirect_uri = 'http://127.0.0.1:8000/z/ding_back/'
    # 获取code
    code = request.GET.get("code")
    t = time.time()
    # 时间戳
    timestamp = str((int(round(t * 1000))))
    # 密钥
    appSecret = 'Njh7SJwIE-MOoZa9P7nxgFf18iNOzCS2KvUaBybQ1xjTszXRA96XDvrTgttDHhVf'
    # 构造签名
    signature = base64.b64encode(
        hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
    # 请求接口，换取钉钉用户名
    payload = {'tmp_auth_code': code}
    headers = {'Content-Type': 'application/json'}
    # 导requests
    import requests
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
        signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoar91fvryq6pugb1nx",
                        data=json.dumps(payload), headers=headers)

    re_dict = json.loads(res.text)
    print(re_dict)
    # 判断是否为第一次登录
    user = UserModel.objects.filter(username=str("dingding_" + re_dict['user_info']['nick'])).first()

    sina_id = ''
    user_id = ''

    if user:
        # 代表曾经用过钉钉登录
        sina_id = user.username
        user_id = user.id
    else:
        # 代表首次登录，入库
        user = UserModel(username=str("dingding_" + re_dict['user_info']['nick']), password='')
        # 保存入库
        user.save()
        sina_id = str(re_dict.get('user_info'))
        # 查询用户id
        user = UserModel.objects.filter(username=str("dingding_" + re_dict['user_info']['nick'])).first()
        user_id = user.id

    # 进行跳转
    return redirect("http://127.0.0.1:8080/myback?sina_id=" + str(sina_id) + "&uid=" + str(user_id))


# 码云三方登录
class Gitee(View):
    def get(self, request):
        return redirect(
            "https://gitee.com/oauth/authorize?client_id=7f611851ce2cbd381390632e50e10ab00108a207dcc00d6c8de686a40fd7cd15&redirect_uri=http://127.0.0.1:8000/z/git_back/&response_type=code")


class GiteeBack(View):
    def get(self, request):
        code = request.GET.get("code", None)
        r = requests.post(
            "https://gitee.com/oauth/token?grant_type=authorization_code&code=%s&client_id=7f611851ce2cbd381390632e50e10ab00108a207dcc00d6c8de686a40fd7cd15&redirect_uri=http://127.0.0.1:8000/z/git_back/&client_secret=ec39df1740d798ac832ab3df1ac99aedd04459c6b7d552f43099ef24273554cc" % code)
        print(r.text)
        r = requests.get("https://gitee.com/api/v5/user?access_token=2b8c4824659611c8a920631bb5684008")

        print(r.text)
        name = json.loads(r.text)['name']
        user = UserModel.objects.filter(username=name)
        if user:
            return redirect('http://127.0.0.1:8080/myback')
        else:
            user = UserModel(username=str("gitee_" + name))
            user.save()
            user = UserModel.objects.filter(username=name)
            return redirect('http://127.0.0.1:8080/myback')


# 工单分类
# 递归
def xTree(datas):
    lists = []
    tree = {}
    parent_id = ''
    for i in datas:
        item = i
        tree[item['id']] = item
    root = None
    for i in datas:
        obj = i
        if not obj['pid']:
            root = tree[obj['id']]
            lists.append(root)
        else:
            parent_id = obj['pid']
            if 'childlist' not in tree[parent_id]:
                tree[parent_id]['childlist'] = []
            tree[parent_id]['childlist'].append(tree[obj['id']])
    return lists


class WorkOrderView(APIView):
    # 添加工单分类信息
    def post(self, request):
        name = request.data.get('name')
        pid = request.data.get('pid')
        if pid:
            WorkOrderModel.objects.create(name=name, pid=pid)
        else:
            WorkOrderModel.objects.create(name=name)
        return Response({'msg': '添加成功'})

    def get(self, request):
        # 获取工单列表
        workorder_list = WorkOrderModel.objects.all()
        # 序列化
        workorder_ser = WorkOrderSer(workorder_list, many=True)
        z_list = xTree(workorder_ser.data)
        return Response(z_list)


class Small_WorkOrderView(APIView):
    def get(self, request):
        # 获取工单列表
        workorder_list = WorkOrderModel.objects.all()
        # 序列化
        workorder_ser = WorkOrderSer(workorder_list, many=True)
        return Response(workorder_ser.data)


# MongoDB
# from pymongo import MongoClient
from z_Userapp.MyMongoDB import MyMonge

# 连接MongoDB
client = MyMonge('z_Cate', 'CateTemplate', **{'host': '127.0.0.1', 'port': 27017})


# 获取MongoDB数据
class GetMongo(APIView):
    def get(self, request):
        # 进入数据库
        # db = client.z_Cate
        # 集合
        # zst = db.CateTemplate
        id = request.GET.get('id', None)
        wid = WorkOrderModel.objects.filter(id=id).first()
        if wid.pid == 0:
            data = client.find({'wid': str(wid.id)})
        else:
            data = client.find({'wid': str(wid.pid)})
        return Response(eval(data['name']))


# 工单分类提交和展示详情视图
class StorageView(APIView):
    # 工单分类提交
    def post(self, request):
        # 获取wid
        wid = request.data.get('id')
        # 获取user_id
        user_id = request.data.get('user_id')
        # 获取工单名 类型转换
        name = request.data.get('name')
        # 获取审核人列表
        checklist = request.data.get('checklist')
        print(checklist)
        qnimg = request.data.get('qnimg')
        # 设置审核人为第一个数据
        now_check = checklist[0]
        storage = StorageModel.objects.filter(uid=user_id, wid=wid).first()

        work = WorkOrderModel.objects.filter(id=wid).first()  # 获取工单分类名
        xx_name = f'你收到了一条需要审核的{work.name}工单'  # 消息盒子的内容

        if storage:
            StorageModel.objects.filter(uid=user_id, wid=wid).update(uid=user_id, wid=wid, message=name,
                                                                     checklist=str(checklist), start=1,
                                                                     now_check=str(now_check), qnimg=qnimg)
            if type(now_check) == list:
                for i in now_check:
                    NestedList.objects.create(sid_id=storage.id, uid=i)
                    # 添加到消息盒子
                    MessageModel.objects.create(name=xx_name, wid_id=wid, uid_id=i)
            else:
                NestedList.objects.create(sid_id=storage.id, uid=now_check)
                MessageModel.objects.create(name=xx_name, wid_id=wid, uid_id=now_check)
        else:
            storage1 = StorageModel.objects.create(uid_id=user_id, wid_id=wid, message=name, checklist=str(checklist),
                                                   start=1, now_check=str(now_check), qnimg=qnimg)
            if type(now_check) == list:
                for i in now_check:
                    NestedList.objects.create(sid_id=storage1.id, uid=i)
                    # 添加到消息盒子
                    MessageModel.objects.create(name=xx_name, wid_id=wid, uid_id=i)
            else:
                NestedList.objects.create(sid_id=storage1.id, uid=now_check)
                MessageModel.objects.create(name=xx_name, wid_id=wid, uid_id=now_check)
        return Response({'msg': '添加成功', 'code': 200})

        # for index, i in enumerate(checklist):
        #     user = UserModel.objects.filter(id=i).first()
        #     name[f'审核人{index + 1}'] = user.username
        # name = str(name)
        # checklist = str(checklist)
        # print(user_id)
        # print(name)
        # 过滤查询
        # StorageList = StorageModel.objects.filter(uid=user_id, wid=wid).first()
        # 如果存在则修改工单
        # if StorageList:
        #     StorageModel.objects.filter(uid=user_id, wid=wid).update(uid=user_id, wid=wid, message=name,checklist=checklist, now_check=now_check, start=1,qnimg=qnimg)
        # # 不存在则创建一个工单
        # else:
        #     StorageModel.objects.create(uid_id=user_id, wid_id=wid, message=name, checklist=checklist,
        #                                 now_check=now_check, start=1,qnimg=qnimg)
        # # 返回成功信息
        # return Response({'msg': '恭喜您，成功提交', 'code': 200})

    # 工单详情展示
    def get(self, request):
        # 获取用户id
        user_id = request.GET.get('user_id')
        # 获取查询集
        storagelist = StorageModel.objects.filter(uid_id=user_id)
        # print(storagelist)
        # 定义一个空列表，用来存放查询集里面的数据
        k_list = []
        # 循环查询集
        for i in storagelist:
            print(i.message)
            # 定义一个字典
            data = {}
            # 字典里存放工单数据 并强转其类型
            data['message'] = eval(i.message)
            data['start'] = i.start

            if type(eval(i.now_check)) == list:
                now_check = eval(i.checklist).index(eval(i.now_check))
            else:
                now_check = eval(i.checklist).index(int(i.now_check))

            # now_check=eval(i.checklist).index(int(i.now_check))

            data['index'] = now_check
            data['qnimg'] = i.qnimg
            datalist = []
            for index, i in enumerate(eval(i.checklist)):
                datalist1 = []
                if type(i) == list:
                    for j in i:
                        user = UserModel.objects.filter(id=j).first()
                        datalist1.append(user.username)
                    datalist1 = ','.join(datalist1)
                    datalist.append(datalist1)
                else:
                    user = UserModel.objects.filter(id=i).first()
                    datalist.append(user.username)
                data['checklist'] = datalist

                # user = UserModel.objects.filter(id=i).first()
            # 把数据添加到 k_list
            k_list.append(data)
        # 返回列表
        return Response(k_list)


# 审核视图
class CheckView(APIView):
    # 审核
    def post(self, request):
        # 获取uid
        # uid = request.GET.get('uid')
        # 获取审核状态
        start = int(request.data.get('start'))
        # 获取id
        id = request.GET.get('id')
        return SimpleFactory.PlantExecute(start, id)
        # 判断，如果审核状态为2（2--通过）
        # if start == 2:
        #     # 过滤工单表 取第一条审核数据
        #     storage = StorageModel.objects.filter(now_check=uid, id=id, start=1).first()
        #     # 把取出来的审核人列表进行强转
        #     storage1 = eval(storage.checklist)
        #     # 并获取其下标
        #     index = storage1.index(int(uid))
        #     # 得到审核人列表长度
        #     length = len(eval(storage.checklist))
        #     # 如果审核人列表长度等于下标+1的话
        #     if length == index + 1:
        #         # 修改当前审核人的审核状态为审核已通过
        #         StorageModel.objects.filter(now_check=uid, id=id).update(start=2)
        #     else:
        #         StorageModel.objects.filter(now_check=uid, id=id).update(now_check=storage1[index + 1])
        #     return Response({'msg': '审核通过', 'code': 200})
        #
        # if start == 3:
        #     storage = StorageModel.objects.filter(now_check=uid, id=id, start=1).first()
        #     storage1 = eval(storage.checklist)
        #     index = storage1.index(int(uid))
        #     if index == 0:
        #         StorageModel.objects.filter(now_check=uid, id=id).update(start=3)
        #     else:
        #         StorageModel.objects.filter(now_check=uid, id=id).update(start=3, now_check=storage1[index - 1])
        #     return Response({'msg': '审核未通过', 'code': 400})
        # return Response({})

    # 获取当前审核人信息
    def get(self, request):
        uid = int(request.GET.get('uid'))
        nest = NestedList.objects.filter(uid=uid)
        storage_list = []
        for i in nest:
            work = StorageModel.objects.filter(id=i.sid_id).first()
            data = {}
            data['id'] = work.id
            data['message'] = eval(work.message)
            storage_list.append(data)
        print(storage_list)
        MessageModel.objects.filter(uid=uid, read=0).update(read=1)
        return Response(storage_list)


# 消息盒子视图
class MessageView(APIView):
    # 获取信息
    def get(self, request):
        uid = request.GET.get('uid')
        print(uid)
        message = MessageModel.objects.filter(uid_id=uid, read=0)
        print(len(message))
        return Response({'count': len(message)})


# 七牛云token
from qiniu import Auth


def qiniu_token():
    qn = Auth('vkoJGPbnvO-zwjVX3DcVJnXtpt9gclvnH5N_A4he', 'Mab055XtHiEYRRoyLEn02JBsY2kRnDAsmonQdhiT')
    # 指定上传空间, 返回token值
    token = qn.upload_token('shixun-p8')
    return token


class UpTokenView(View):
    def get(self, request):
        """
        七牛云token接口
        """
        return JsonResponse({'token': qiniu_token()})


import upyun


# 定义文件上传类
class UploadFile(View):
    def post(self, request):
        file = request.FILES.get('file')
        print(file)
        up = upyun.UpYun('shixun-p8', username='coisnini', password='5LQiEB6YUY4aTIHQDNLMPpVf2QpnNeft')
        headers = {'x-gmkerl-rotate': '180'}
        for chunk in file.chunks():
            res = up.put('/touxiang1.jpg', chunk, checksum=True, headers=headers)
        # 返回结果
        return HttpResponse(json.dumps({'filename': file.name}), content_type='application/json')


class ShowGong(APIView):

    def post(self, request):
        mess = MessageModel.objects.all().order_by('-datetime')

        ser = MessageSer(mess, many=True)

        return Response(ser.data)


class MessageCehuiView(APIView):
    def post(self, request):
        uid = request.data.get('uid')
        text = request.data.get('text')
        FaModel.objects.create(uid=uid, text=text, che=0)
        set = FaModel.objects.filter(uid=uid).last()
        set1 = str(set.id)
        # 保存到redis
        a = set1 + '1234'
        print(a,'-------------')
        r = redis.Redis()
        r.hmset(a, {'id': set1, 'uid': uid, 'text': text})
        # 过期删除数据库120s
        r.expire(a, 120)
        return Response({'msg': '发送成功'})

    def put(self, request):
        id = request.data.get('id')
        a = FaModel.objects.filter(id=id)
        r = redis.Redis()
        # 查看数据库名是否存在
        res = r.hgetall(str(id) + '1234')
        print(res, '-----------------')
        if res:
            a.update(che=1)
            return Response({'msg': '撤销成功'})
        return Response({'msg': '超过2分钟无法撤回'})

    def get(self, request):

        mid = request.GET.get('mid')

        mess = MessageModel.objects.filter(id=mid).first()

        ser = MessageSer(mess)

        if mess.read == 0:

            mess.read += 1
            mess.save()
            return Response(ser.data)

        else:

            return Response(ser.data)


class ShowXiao(APIView):

    def get(self, request):
        set = FaModel.objects.all().order_by('-che')

        ser = FaSer(set, many=True)

        return Response(ser.data)


class RidesAPI(APIView):

    def post(self,request):

        pass


from dwebsocket.decorators import accept_websocket

#接收前端信息

@accept_websocket
def test_socket(request):
    if request.is_websocket():
        for message in request.websocket:
            c=str(message,encoding='utf-8')
            print(c)
            request.websocket.send(message)


@accept_websocket
def test_websocket(request):
    if request.is_websocket():
        while 1:
            time.sleep(1) ## 向前端发送时间
            dit = {
                'time':time.strftime('%Y.%m.%d %H:%M:%S',time.localtime(time.time()))
            }
            request.websocket.send(json.dumps(dit))
















